/**
 * 
 */
package spatial.geometry;

import java.awt.geom.Rectangle2D;

/**
 * 
 * A rectangle is defined with its lower-left point, width and height.
 * 
 * Note that the semantic of "lower-left" is what it mean in our daily used
 * Euclidean space, i.e. where Y axis grows from lower to upper (in contrast to
 * the one used in java2d where the Y axis grows from upper to lower).
 * 
 * The implementation is in fact a wrapper of the
 * java.awt.geom.Rectangle2D.Double. Although it uses the upper-left corner to
 * define a rectangle, its Y axis direction is opposite to our Y axis. Therefore
 * it in fact defines the lower-left corner in our system.
 * 
 *  ** Modified on Jan 18, 2008 Make this class an extension of java's
 * Rectangle2D.Double (rather than a wrapper). The purpose of this modification
 * is to make it inter-operable with other java.awt.geom classes.
 * 
 * @author wu wei
 * 
 */
public class Rectangle extends Rectangle2D.Double implements BasicShape {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5153469260608490549L;
	Location lowerLeft;
	
	public Rectangle(Location lowerLeft, double width, double height) {
		super(lowerLeft.getX(), lowerLeft.getY(), width, height);
		this.lowerLeft = lowerLeft;
	}
	
	public Location getLowerLeft() {
		return this.lowerLeft;
	}
	
	public Location getLowerRight() {
		return new Location(this.lowerLeft.getX() + this.getWidth(),
				this.lowerLeft.getY());
	}

	public Location getUpperLeft() {
		return new Location(this.lowerLeft.getX(), this.lowerLeft.getY()
				+ this.getHeight());
	}

	public Location getUpperRight() {
		return new Location(this.lowerLeft.getX() + this.getWidth(),
				this.lowerLeft.getY() + this.getHeight());
	}

	public double getWidth() {
		return super.getWidth();
	}

	public double getHeight() {
		return super.getHeight();
	}

	/**
	 * Move this shape such that the given location is its center.
	 * 
	 * @param loc
	 */
	public void centerTo(Location loc) {
		/**
		 * <pre>
		 * new lower left corner = new center.x - width/2, new center.y - height/2
		 * set lowerleft location
		 * </pre>
		 * 
		 */
		Location new_lower_left = new Location(
				loc.getX() - this.getWidth() / 2, loc.getY() - this.getHeight()
						/ 2);
		this.lowerLeft = new_lower_left;
		double w = this.getWidth();
		double h = this.getHeight();
		super.setFrame(this.lowerLeft.getX(), this.lowerLeft.getY(), w, h);
	}

	public boolean contains(Location l) {
		return super.contains(l.getX(), l.getY());
	}

	public boolean contains(Rectangle r) {
		return super.contains(r);
	}

	public Rectangle getRectBounds() {
		return this;
	}

	public boolean intersects(Rectangle rec) {
		return super.intersects(rec);
	}

	public boolean intersects(Circle c) {
		return c.intersects(this);
	}

	public String toString() {
		String s = "Rectangle[";
		s = s + this.lowerLeft.toParenthesisString();
		s = s + ",w=" + this.getWidth();
		s = s + ",h=" + this.getHeight();
		s = s + "]";
		return s;
	}

	public Rectangle clone() {
		return new Rectangle(this.lowerLeft, this.getWidth(), this.getHeight());
	}

	public BasicShape deepClone() {
		return new Rectangle(this.lowerLeft, this.getWidth(), this.getHeight());
	}

}
